#pragma once

#include <iostream>
#include <random>
#include <sstream>
#include <iomanip>
#include <atomic>
#include <string>
#include <fstream>

#include "logger.hpp"

std::string uuid() {
    std::random_device rd;
    //以设备为随机数
    std::mt19937 generator(rd());
    //设置范围
    std::uniform_int_distribution<int> distribution(0,255);

    std::stringstream ss;
    for(int i =0; i < 6; i++) {
        if(i == 2) ss << "-";
        ss << std::setw(2) << std::setfill('0') << std::hex << distribution(generator);        
    }

    ss << "-";
    //生成2字节的编号数字  结尾以0 1 2 ... 
    static std::atomic<short> idx(0);
    short tmp = idx.fetch_add(idx);
    ss << std::setw(4) << std::setfill('0') << std::hex << tmp;

    return ss.str();
}

bool readFile(const std::string& filename,std::string& body) {
    LOG_DEBUG("开始读取文件数据");
    //将读取到的数据放到body中
    std::ifstream ifs(filename,std::ios::binary | std::ios::in);
    if(ifs.is_open() == false) {
        LOG_ERROR("打开文件{}失败",filename);
        return false;
    }

    ifs.seekg(0,std::ios::end);
    //获取文件大小
    ssize_t file_len = ifs.tellg();
    ifs.seekg(0,std::ios::beg);
    body.resize(file_len);
    ifs.read(&body[0],file_len);
    if(ifs.good() == false) {
        LOG_ERROR("读取文件{}数据失败",filename);
        ifs.close();
        return false;
    }

    ifs.close();
    return true;
}

bool writeFile(const std::string& filename,const std::string& body) {
    //将body中的数据写入到fikename中
    std::ofstream ofs(filename,std::ios::out | std::ios::trunc | std::ios::binary);
    if(ofs.is_open() == false) {
        LOG_ERROR("打开文件{}失败",filename);
    }

    ofs.write(body.c_str(),body.size());
    if(ofs.good() == false) {
        LOG_ERROR("读取文件{}失败",filename);
        ofs.close();
        return false;
    }

    ofs.close();
    return true;
}

std::string vcode() {
    std::random_device rd;//实例化设备随机数对象-用于生成设备随机数
    std::mt19937 generator(rd());//以设备随机数为种子，实例化伪随机数对象
    std::uniform_int_distribution<int> distribution(0,9); //限定数据范围

    std::stringstream ss;
    for (int i = 0; i < 4; i++) {
        ss << distribution(generator);
    }
    return ss.str();
}